package com.zx.zxpicture.interfaces.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zx.zxpicture.infrstructure.annotation.AuthCheck;
import com.zx.zxpicture.infrstructure.common.BaseResponse;
import com.zx.zxpicture.infrstructure.common.ErrorCode;
import com.zx.zxpicture.infrstructure.common.ResultUtils;
import com.zx.zxpicture.domain.user.objectvalue.UserConstant;
import com.zx.zxpicture.infrstructure.exception.BusinessException;
import com.zx.zxpicture.infrstructure.exception.ThrowUtils;
import com.zx.zxpicture.interfaces.assembler.SpaceAssembler;
import com.zx.zxpicture.shared.auth.SpaceUserAuthManager;
import com.zx.zxpicture.interfaces.dto.space.SpaceAddRequest;
import com.zx.zxpicture.interfaces.dto.space.SpaceLevel;
import com.zx.zxpicture.interfaces.dto.space.SpaceQueryRequest;
import com.zx.zxpicture.interfaces.dto.space.SpaceUpdateRequest;
import com.zx.zxpicture.domain.space.entity.Space;
import com.zx.zxpicture.domain.user.entity.User;
import com.zx.zxpicture.interfaces.vo.SpaceVO;
import com.zx.zxpicture.application.service.SpaceApplicationService;
import com.zx.zxpicture.application.service.UserApplicationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
@RequestMapping("/space")
@Slf4j
public class SpaceController {
    @Autowired
    private SpaceApplicationService spaceApplicationService;
    @Autowired
    private UserApplicationService userApplicationService;
    @Resource
    private SpaceUserAuthManager spaceUserAuthManager;

    /**
     * 创建空间
     * @param spaceAddRequest 创建空间请求
     * @param request 请求
     * @return 空间id
     */
    @PostMapping("/add")
    public BaseResponse<Long> addSpace(@RequestBody SpaceAddRequest spaceAddRequest, HttpServletRequest request) {
        if(spaceAddRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"创建空间请求为空");
        }
        User loginUser = userApplicationService.getLoginUser(request);
        long newSpaceId = spaceApplicationService.addSpace(spaceAddRequest, loginUser);
        return ResultUtils.success(newSpaceId);
    }

    /**
     * 更新空间
     * @param spaceUpdateRequest
     * @return
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateSpace(@RequestBody SpaceUpdateRequest spaceUpdateRequest) {
        if (spaceUpdateRequest == null || spaceUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 将实体类和 DTO 进行转换
        Space space = SpaceAssembler.toSpaceEntity(spaceUpdateRequest);
        // 自动填充数据
        spaceApplicationService.fillSpaceBySpaceLevel(space);
        // 数据校验
        spaceApplicationService.validSpace(space, false);
        // 判断是否存在
        long id = spaceUpdateRequest.getId();
        Space oldSpace = spaceApplicationService.getById(id);
        ThrowUtils.throwIf(oldSpace == null, ErrorCode.NOT_FOUND_ERROR);
        // 操作数据库
        boolean result = spaceApplicationService.updateById(space);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 分页获取空间列表（仅管理员可用）
     */
    @PostMapping("/list/space")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<Space>> listSpaceByPage(@RequestBody SpaceQueryRequest spaceQueryRequest) {
        long current = spaceQueryRequest.getCurrent();
        long size = spaceQueryRequest.getPageSize();
        // 分页查询数据库
        Page<Space> spacePage = spaceApplicationService.page(new Page<>(current, size),
                spaceApplicationService.getQueryWrapper(spaceQueryRequest));
        return ResultUtils.success(spacePage);
    }

    /**
     * 用户分页获取空间列表（封装类）
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<SpaceVO>> listSpaceVOByPage(@RequestBody SpaceQueryRequest spaceQueryRequest,
                                                             HttpServletRequest request) {
        //校验权限
        Long userId = spaceQueryRequest.getUserId();
        if(userId == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户id为空");
        }
        User loginUser = userApplicationService.getLoginUser(request);
        if(!userId.equals(loginUser.getId())){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"没有权限操作该空间");
        }
        long current = spaceQueryRequest.getCurrent();
        long size = spaceQueryRequest.getPageSize();
        // 分页查询数据库
        Page<Space> spacePage = spaceApplicationService.page(new Page<>(current, size),
                spaceApplicationService.getQueryWrapper(spaceQueryRequest));
        return ResultUtils.success(spaceApplicationService.getSpaceVOPage(spacePage,request));
    }

    /**
     * 根据 id 获取空间（封装类）
     * **如果有空间id，那么只能是空间管理员才能查看
     */
    @GetMapping("/get/vo")
    public BaseResponse<SpaceVO> getSpaceVOById(long id, HttpServletRequest request) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        Space space = spaceApplicationService.getById(id);
        ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR);
        User loginUser = userApplicationService.getLoginUser(request);
        SpaceVO spaceVO = spaceApplicationService.getSpaceVO(space, request);
        //设置权限列表
        spaceVO.setPermissionList(spaceUserAuthManager.getPermissionList(space,loginUser));
        // 获取封装类
        return ResultUtils.success(spaceVO);
    }

    /**
     * 将空间等级枚举转换为对象并返回
     * @return
     */
    @GetMapping("/list/level")
    public BaseResponse<List<SpaceLevel>> listSpaceLevel() {
        return spaceApplicationService.listSpaceLevel();
    }
}
